package com.github.data_manage.util

import cn.hutool.core.date.DateUtil
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException
import kotlin.math.abs

/**
 *@author CHN
 *@since 2024-08-11 16:38
 */
class DateTimeUtils : DateUtil() {

    companion object {

        private val monthlyDateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM")


        fun parseDateTime(time: CharSequence): LocalDateTime {
            return parse(time).toLocalDateTime()
        }

        fun toMonthlyString(localDate: LocalDate): String {
            return monthlyDateTimeFormatter.format(localDate)
        }

        fun LocalDateTime.atStartOfDay(): LocalDateTime {
            return LocalDateTime.of(toLocalDate(), LocalTime.MIN)
        }

        fun LocalDateTime.atEndOfDay(): LocalDateTime {
            return LocalDateTime.of(toLocalDate(), LocalTime.MAX)
        }

        fun LocalDateTime.atEndOfMonth(): LocalDateTime {
            return LocalDateTime.of(LocalDate.of(year, month, month.maxLength()), LocalTime.MAX)
        }

        fun LocalDate.atEndOfMonth(): LocalDate {
            return LocalDate.of(year, month, month.length(isLeapYear))
        }

        fun LocalDate.atStartOfYear(): LocalDate {
            return LocalDate.of(year, 1, 1)
        }

        fun LocalDate.atEndOfYear(): LocalDate {
            return LocalDate.of(year, 12, 31)
        }

        fun LocalDate.getYearTimeRange(): Pair<LocalDate, LocalDate> {
            return Pair(this.atStartOfYear(), this.atEndOfYear())
        }


        val yearRegex = Regex("^(19|20)\\d{2}$")

        val monthRegex = Regex("^(19|20)\\d{2}-(0[1-9]|1[0-2])$")

        val dayRegex = Regex("^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$")

        fun tryParse(text: CharSequence): LocalDate? {
            val realText = if (dayRegex.matches(text)) {
                text
            } else if (monthRegex.matches(text)) {
                "$text-01"
            } else if (yearRegex.matches(text)) {
                "$text-01-01"
            } else {
                return null
            }
            return try {
                LocalDate.parse(realText)
            } catch (e: Exception) {
                null
            }
        }

        fun LocalDate.quarter(): Int {
            return when (this.monthValue) {
                1, 2, 3 -> 1
                4, 5, 6 -> 2
                7, 8, 9 -> 3
                10, 11, 12 -> 4
                else -> throw IllegalArgumentException("Invalid local date $this")
            }
        }


        fun betweenMonth(startDate: LocalDate, endDate: LocalDate): Int {
            val yearDiff = endDate.year - startDate.year
            return abs(yearDiff * 12 + (endDate.monthValue - startDate.monthValue))
        }
    }

}


